/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "LED.h"
#include "FT6236.h"
#include "SEEKFREE_IPS114_SPI.h"
#include "SEEKFREE_FONT.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */



// 主要变量
uint8_t Flag_DefiniteTouch = 0;	//标志变量 0 --- 无有效触摸; 1 --- 有有效触摸;
uint8_t Flag_OriginalTouch = 0;	//标志变量 0 --- 无原始触摸; 1 --- 有原始触摸;
uint8_t FlagMemory_OriginalTouch[50];	//记录过去50次标志, 可以据此进行判断有效触摸; 越早的储存位置越靠前
uint8_t Flag_LastDefiniteTouch = 0;// 标志变量 0 --- 刚刚无有效触摸; 1 --- 刚刚有有效触摸;
uint8_t Flag_TriggerDefiniteTouch = 0;// 标志变量 0 --- 未触发新的有效触摸; 1 --- 触发了新的有效触摸;
uint8_t Flag_DeTriggerDefiniteTouch = 0;// 标志变量 0 --- 未发生有效触摸的消失; 1 --- 发生了有效触摸的消失;
FT6236_Touch_TypeDef FT6236_Touch_Structure0;	//触摸结构体

uint8_t Mechine_IsStart = 0; //状态变量 0 --- 洗衣机未开机; 1 --- 洗衣机已开机;
uint8_t Mechine_IsRunning = 0; //状态变量 0 --- 洗衣机暂停; 1 --- 洗衣机运行;
uint8_t Mechine_WaterLevel = 1; //状态变量 洗衣机水位 1~6 默认为1
uint8_t Mechine_Mode = 1; //状态变量 洗衣模式 1~6 默认为1

// 辅助变量
uint8_t loopnum = 0;
uint8_t loopnum2 = 0;
uint8_t i1, i2;
uint8_t byte;
uint16_t byte16;
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  LED_Init();
  FT6236_Init();
  ips114_init();
  ips114_clear(WHITE);
  ips114_showstr(0, 0, (uint8_t*)"Washing Mechine Pannal");
  ips114_showstr(0, 1, (uint8_t*)"Control System");
  ips114_showstr(0, 4, (uint8_t*)"IsStarted: No");
  ips114_showstr(0, 5, (uint8_t*)"IsRunning: No");
  ips114_showstr(0, 6, (uint8_t*)"WaterLevel: 1");
  ips114_showstr(0, 7, (uint8_t*)"Mode:       1");
  
  ips114_showstr(0, 11, (uint8_t*)"OFF/ON  Pause   Water   Mode");
  ips114_showstr(0, 12, (uint8_t*)"         /Run   Level");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		//测试程序
//		loopnum %= 100;
//		if(loopnum == 10){
//			loopnum2++;
//			HAL_UART_Transmit(&huart1, &loopnum2, 1, 10);
//			ips114_showuint8(50, 50, loopnum2);
//		}
		
		// 正式程序
		
		
		
		// STEP 1 根据触摸屏状态确定是否存在原始触摸
		FT6236_GetTouch(&FT6236_Touch_Structure0);
		if(FT6236_Touch_Structure0.Event == FT6236_Touch_Event_Contect){//判断逻辑: 事件为接触
			Flag_OriginalTouch = 1;
		}else{
			Flag_OriginalTouch = 0;
		}

		// STEP 2 更新过去10次触摸记录
		for(i1 = 0; i1 <= 8; i1++){
			FlagMemory_OriginalTouch[i1] = FlagMemory_OriginalTouch[i1 + 1];
		}
		FlagMemory_OriginalTouch[9] = Flag_OriginalTouch;

		// STEP 3 记录刚才是否有有效触摸 根据触摸记录得到是否有确定触摸
		Flag_LastDefiniteTouch = Flag_DefiniteTouch;
		
		Flag_DefiniteTouch = 1;
		for(i2 = 0; i2 < 10; i2 ++){
			Flag_DefiniteTouch &= FlagMemory_OriginalTouch[i2];//每个进行与运算
		}
		
		// STEP 4 判断是否有新的有效触摸 判断是否原来的有效触摸消失
		if(Flag_LastDefiniteTouch == 0 && Flag_DefiniteTouch == 1){
			Flag_TriggerDefiniteTouch = 1;
		}else{
			Flag_TriggerDefiniteTouch = 0;
		}
		
		if(Flag_LastDefiniteTouch == 1 && Flag_DefiniteTouch == 0){
			Flag_DeTriggerDefiniteTouch = 1;
		}else{
			Flag_DeTriggerDefiniteTouch = 0;
		}

		// STEP 5 根据状态做出反应 状态进行改变
		if(Flag_TriggerDefiniteTouch){
			LED_ON();
			ips114_showstr(0, 2, (uint8_t*)"PRESS");
			HAL_UART_Transmit(&huart1, (uint8_t*)&"\n\nPRESS ", 8, 10);
			if(FT6236_Touch_Structure0.FT6236_Touch_X >= 0x7F){
				if(FT6236_Touch_Structure0.FT6236_Touch_Y > 0xC0){//按到开关键
					HAL_UART_Transmit(&huart1, (uint8_t*)&"OFF/ON ", 7, 10);
					Mechine_IsStart = 1 - Mechine_IsStart;
					if(Mechine_IsStart == 0){//关闭状态时不能运行
						Mechine_IsRunning = 0;
					}
		
					ips114_showstr(0, 3, (uint8_t*)"OFF/ON     ");
				}else if(FT6236_Touch_Structure0.FT6236_Touch_Y > 0x80){//按到暂停键
					HAL_UART_Transmit(&huart1, (uint8_t*)&"Pause/Run ", 10, 10);
					if(Mechine_IsStart){
						Mechine_IsRunning = 1 - Mechine_IsRunning;
					}
					ips114_showstr(0, 3, (uint8_t*)"Pause/Run   ");
				}else if(FT6236_Touch_Structure0.FT6236_Touch_Y > 0x40){//按到水位切换键
					HAL_UART_Transmit(&huart1, (uint8_t*)&"Water Level ", 12, 10);
					Mechine_WaterLevel = Mechine_WaterLevel % 6 + 1;
					ips114_showstr(0, 3, (uint8_t*)"Water Level");
				}else{//按到模式切换键
					HAL_UART_Transmit(&huart1, (uint8_t*)&"Mode ", 5, 10);
					Mechine_Mode = Mechine_Mode % 6 + 1;
					ips114_showstr(0, 3, (uint8_t*)"Mode       ");
				}
				
				//更新屏幕状态并通过串口发送
				HAL_UART_Transmit(&huart1, (uint8_t*)&"\nIsStarted: ", 12, 10);
				if(Mechine_IsStart){
					HAL_UART_Transmit(&huart1, (uint8_t*)&"Yes", 3, 10);
					ips114_showstr(11, 4, (uint8_t*)"Yes");
				}else{
					HAL_UART_Transmit(&huart1, (uint8_t*)&"No", 2, 10);
					ips114_showstr(11, 4, (uint8_t*)"No ");
				}
				
				HAL_UART_Transmit(&huart1, (uint8_t*)&"\nIsRunning: ", 12, 10);
				if(Mechine_IsRunning){
					HAL_UART_Transmit(&huart1, (uint8_t*)&"Yes", 3, 10);
					ips114_showstr(11, 5, (uint8_t*)"Yes");
				}else{
					HAL_UART_Transmit(&huart1, (uint8_t*)&"No", 2, 10);
					ips114_showstr(11, 5, (uint8_t*)"No ");
				}
				
				HAL_UART_Transmit(&huart1, (uint8_t*)&"\nWater Level: ", 14, 10);
				Mechine_WaterLevel += '0';
				HAL_UART_Transmit(&huart1, &Mechine_WaterLevel, 1, 10);
				ips114_showchar(12*8, 6*16, Mechine_WaterLevel);
				Mechine_WaterLevel -= '0';
				
				
				HAL_UART_Transmit(&huart1, (uint8_t*)&"\nMode: ", 7, 10);
				Mechine_Mode += '0';
				HAL_UART_Transmit(&huart1, &Mechine_Mode, 1, 10);
				ips114_showchar(12*8, 7*16, Mechine_Mode);
				Mechine_Mode -= '0';
				
				
			}
			HAL_Delay(500);
		}
		if(Flag_DeTriggerDefiniteTouch){
			LED_OFF();
			HAL_UART_Transmit(&huart1, (uint8_t*)&"\n\nLIFT", 6, 10);
			//更新屏幕状态并通过串口发送
			HAL_UART_Transmit(&huart1, (uint8_t*)&"\nIsStarted: ", 12, 10);
			if(Mechine_IsStart){
				HAL_UART_Transmit(&huart1, (uint8_t*)&"Yes", 3, 10);
			}else{
				HAL_UART_Transmit(&huart1, (uint8_t*)&"No", 2, 10);
			}
			
			HAL_UART_Transmit(&huart1, (uint8_t*)&"\nIsRunning: ", 12, 10);
			if(Mechine_IsRunning){
				HAL_UART_Transmit(&huart1, (uint8_t*)&"Yes", 3, 10);
			}else{
				HAL_UART_Transmit(&huart1, (uint8_t*)&"No", 2, 10);
			}
			
			HAL_UART_Transmit(&huart1, (uint8_t*)&"\nWater Level: ", 14, 10);
			Mechine_WaterLevel += '0';
			HAL_UART_Transmit(&huart1, &Mechine_WaterLevel, 1, 10);
			Mechine_WaterLevel -= '0';
			
			
			HAL_UART_Transmit(&huart1, (uint8_t*)&"\nMode: ", 7, 10);
			Mechine_Mode += '0';
			HAL_UART_Transmit(&huart1, &Mechine_Mode, 1, 10);
			Mechine_Mode -= '0';
			
			ips114_showstr(0, 2, (uint8_t*)"LIFT ");
			ips114_showstr(0, 3, (uint8_t*)"           ");
		}
		
	
		HAL_Delay(10);//扫描频率 100次/秒 10ms/次
		
		loopnum++;
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
